package cn.uncode.baas.server.internal.module.rest;

import java.util.Map;

import javax.script.ScriptException;

import cn.uncode.dal.internal.util.message.Messages;
import cn.uncode.baas.server.cache.SystemCache;
import cn.uncode.baas.server.dto.RestMethod;
import cn.uncode.baas.server.exception.MethodNotFoundException;
import cn.uncode.baas.server.exception.ValidateException;
import cn.uncode.baas.server.internal.Executer;
import cn.uncode.baas.server.internal.RequestMap;
import cn.uncode.baas.server.internal.context.RestContextManager;
import cn.uncode.baas.server.internal.module.IModules;
import cn.uncode.baas.server.internal.script.ScriptResult;
import cn.uncode.baas.server.utils.DataUtils;
import cn.uncode.baas.server.utils.WebApplicationContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class RestModule implements IRestModule {
	
	
	@Autowired
	private RestTemplate restTemplate;
	
	public Object invoke(Object param) throws ScriptException, NoSuchMethodException, ValidateException, MethodNotFoundException {
		Map<String, Object> map = DataUtils.convert2Map(param);
		if(!map.containsKey(REST_METHOD)){
			throw new ScriptException(Messages.getString("RuntimeError.10", "method"));
		}
		if(!map.containsKey(RestMethod.OPTION)){
			throw new ScriptException(Messages.getString("RuntimeError.10", "option"));
		}
		if(!map.containsKey(RestMethod.VERSION)){
			throw new ScriptException(Messages.getString("RuntimeError.10", "version"));
		}
		String bucket = null;
		if(map.containsKey(RestMethod.BUCKET)){
			bucket = String.valueOf(map.get(RestMethod.BUCKET));
		}else{
			bucket = RestContextManager.getContext().getBucket();
		}
		String mehtod = String.valueOf(map.get(REST_METHOD));
		String option = String.valueOf(map.get(RestMethod.OPTION));
		String version = String.valueOf(map.get(RestMethod.VERSION));
		RequestMap<String, Object> params = DataUtils.convert2Map(map.get(REST_PARAMS));
		ScriptResult scriptResult = null;
		RestMethod restMethod = SystemCache.getRestMethod(bucket, mehtod, option, version);
		if(restMethod != null){
			IModules modules = WebApplicationContextUtil.getBean("defaultModules", IModules.class);
			boolean cacheEnable = (restMethod.getSeconds() != -1);
			scriptResult = Executer.execute(bucket, mehtod, option,
					version, params, cacheEnable, modules, null);
		}
		
		if(null == scriptResult){
			return null;
		}else{
			return scriptResult.getResult();
		}
	}
	
	
	public Map<String, Object> get(String url) {
		@SuppressWarnings("unchecked")
		Map<String, Object> result = restTemplate.getForObject(url, Map.class); 
		return result;
	}
	
	public Map<String, Object> get(String url, Object param) {
		Map<String, Object> maps = DataUtils.convert2Map(param);
		@SuppressWarnings("unchecked")
		Map<String, Object> result = restTemplate.getForObject(url, Map.class, maps); 
		return result;
	}
	
	public Map<String, Object> post(String url, Object param) {
		Map<String, Object> maps = DataUtils.convert2Map(param);
		@SuppressWarnings("unchecked")
		Map<String, Object> result = restTemplate.postForObject(url, null, Map.class, maps);
		return result;
	}
	
	public void put(String url, Object param) {
		Map<String, Object> maps = DataUtils.convert2Map(param);
		restTemplate.put(url, null, maps);
	}

	public void delete(String url, Object param) {
		Map<String, Object> maps = DataUtils.convert2Map(param);
		restTemplate.delete(url, maps);
	}

}
